package com.eliza.music.view.music.play

import android.annotation.SuppressLint
import android.media.MediaPlayer
import android.media.MediaPlayer.SEEK_CLOSEST
import android.net.Uri
import android.os.Build
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.automirrored.filled.List
import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.rounded.Close
import androidx.compose.material.icons.rounded.PlayArrow
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.ModalBottomSheetDefaults
import androidx.compose.material3.Slider
import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.TileMode
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import coil.compose.rememberAsyncImagePainter
import com.eliza.library.utils.compose.ImageBuild
import com.eliza.music.compoment.music.Disc
import com.eliza.music.compoment.music.SongView
import com.eliza.music.model.vm.PlayingMusicVm
import com.eliza.music.model.vm.PlayingSetting
import com.eliza.music.model.vm.PlayingSettingVm
import com.eliza.music.ui.theme.FontSize
import com.eliza.music.ui.theme.PaddingSize
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File

@SuppressLint("RememberReturnType")
@Preview(showSystemUi = true)
@Composable
private fun Preview() {
    val vm: PlayingMusicVm = hiltViewModel()
    val setting: PlayingSettingVm = hiltViewModel()
    PlayingX.OpenPlayingPage(setting = setting.setting.collectAsState(), vm = vm)
}


object PlayingX {
    @OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun OpenPlayingListPage(
        setting: State<PlayingSetting>, vm: PlayingMusicVm, settingVm: PlayingSettingVm
    ) {
        val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
        if (setting.value.showPlaylist.value) {
            val songs = vm.songs.collectAsState().value
            ModalBottomSheet(
                modifier = Modifier.fillMaxHeight(0.7f),
                onDismissRequest = {
                    settingVm.showPlaylist(false)
                },
                sheetState = sheetState,
                shape = RoundedCornerShape(50),
                properties = ModalBottomSheetDefaults.properties(),
                scrimColor = Color.Transparent,
                contentColor = Color.Transparent,
            ) {
                SongView.ItemInPlayList(data = songs, modifier = Modifier.clickable {

                })
            }
        }
    }

    @OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun OpenPlayingPage(
        modifier: Modifier = Modifier,
        setting: State<PlayingSetting>,
        vm: PlayingMusicVm,
        settingVm: PlayingSettingVm = hiltViewModel()
    ) {
        val scope = rememberCoroutineScope()
        val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
        if (setting.value.showPlayingPage.value) {
            ModalBottomSheet(
                onDismissRequest = {
                    settingVm.showPlayingPage(false)
                },
                sheetState = sheetState,
                shape = RoundedCornerShape(20.dp),
                scrimColor = Color.Black,
            ) {
                Box(
                    modifier = Modifier.background(
                        brush = Brush.verticalGradient(
                            colors = listOf(
                                Color(80, 133, 133, 220), Color(42, 71, 92, 230)
                            ), tileMode = TileMode.Clamp
                        )
                    ),
                ) {
                    Icon(imageVector = Icons.Default.KeyboardArrowDown,
                        contentDescription = "",
                        tint = Color.White,
                        modifier = Modifier
                            .size(40.dp)
                            .clip(CircleShape)
                            .clickable {
                                scope.launch {
                                    if (sheetState.isVisible) {
                                        sheetState.hide()
                                        settingVm.showPlaylist(false)
                                        settingVm.showPlayingPage(false)
                                    }
                                }
                            })
                    PlayingPage(setting = setting, vm = vm, settingVm = settingVm)
                }
            }
        }
    }

    @Composable
    fun PlayingPageTop(
        modifier: Modifier = Modifier,
        setting: State<PlayingSetting>,
        vm: PlayingMusicVm,
        settingVm: PlayingSettingVm
    ) {
        val song = vm.currentSong
        val infiniteTransition = rememberInfiniteTransition(label = "")
        val rotate by infiniteTransition.animateFloat(
            initialValue = 0f, targetValue = 360f, animationSpec = infiniteRepeatable(
                animation = keyframes {
                    durationMillis = setting.value.animationKeyframesDur * 100
                    0.7f at 500
                }, repeatMode = RepeatMode.Restart
            ), label = "rotate"
        )
        val alpha by infiniteTransition.animateFloat(
            initialValue = 0.5f, targetValue = 1f, animationSpec = infiniteRepeatable(
                animation = keyframes {
                    durationMillis = setting.value.animationKeyframesDur * 100
                    0.7f at 500
                }, repeatMode = RepeatMode.Restart
            ), label = "alpha"
        )
        Box(
            contentAlignment = Alignment.Center, modifier = Modifier
                .then(modifier)
                .fillMaxSize()
        ) {
            Disc(modifier.alpha(alpha))
            Image(
                painter = rememberAsyncImagePainter(
                    model = ImageBuild.CoilImageRequest(
                        LocalContext.current, song.value.icon
                    )
                ),
                contentDescription = "",
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .fillMaxSize(0.4f)
                    .aspectRatio(1f)
                    .shadow(10.dp, shape = CircleShape)
                    .rotate(rotate)
            )
        }
    }

    @Composable
    fun PlayingPage(
        modifier: Modifier = Modifier,
        setting: State<PlayingSetting>,
        vm: PlayingMusicVm,
        settingVm: PlayingSettingVm
    ) {
        Column(
            modifier = Modifier.fillMaxSize()
        ) {
            PlayingPageTop(modifier = Modifier.weight(6f), setting, vm, settingVm)
            PlayingPageSetting(modifier = Modifier.weight(4f), setting, vm, settingVm)
        }
    }

    @Composable
    fun PlayingPageSetting(
        modifier: Modifier = Modifier,
        setting: State<PlayingSetting>,
        vm: PlayingMusicVm,
        settingVm: PlayingSettingVm
    ) {
        val song = vm.currentSong
        val scope = rememberCoroutineScope() // Create a coroutine scope
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .then(modifier),
            verticalArrangement = Arrangement.SpaceBetween,
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            val context = LocalContext.current
            val mediaPlayer = MediaPlayer.create(context, Uri.parse(song.value.uri))
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .background(Color.Transparent),
                horizontalArrangement = Arrangement.Absolute.SpaceAround,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Column(
                    modifier = Modifier
                        .weight(5f)
                        .padding(20.dp)
                ) {
                    Text(
                        text = song.value.title,
                        fontSize = FontSize.Normal.size,
                        color = Color.White
                    )
                    Text(
                        text = song.value.artist,
                        fontSize = FontSize.Small.size,
                        color = Color.White.copy(0.7f)
                    )
                }
                var icx by remember {
                    mutableStateOf(false)
                }
                Icon(
                    modifier = Modifier
                        .weight(1f, false)
                        .clip(CircleShape)
                        .clickable {
                            icx = !icx
                        },
                    imageVector = if (icx) {
                        Icons.Default.Favorite
                    } else {
                        Icons.Default.FavoriteBorder
                    },
                    contentDescription = "",
                )
                Icon(
                    modifier = Modifier
                        .weight(1f)
                        .clip(CircleShape),
                    imageVector = Icons.Default.Email, contentDescription = "",
                )
            }
            var sliderPosition by remember { mutableFloatStateOf(0f) }
            var duration by remember { mutableStateOf(song.value.duration) }
            Text(text = "time:${sliderPosition.toInt()} ${duration}")
            Slider(value = sliderPosition,
                onValueChange = {
                    sliderPosition = it
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        mediaPlayer.seekTo(it.toLong(), SEEK_CLOSEST)
                    } else {
                        mediaPlayer.seekTo(it.toInt())
                    }
                },
                modifier = Modifier.fillMaxWidth(0.9f),
                valueRange = 0f..duration.toFloat(),
                steps = duration.toInt(),
                colors = SliderDefaults.colors(
                    thumbColor = Color.White,
                    activeTrackColor = Color.LightGray,
                ),
                interactionSource = remember { MutableInteractionSource() })

            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(60.dp)
                    .background(Color.Transparent),
                horizontalArrangement = Arrangement.SpaceEvenly,
                verticalAlignment = Alignment.CenterVertically
            ) {
                LaunchedEffect(sliderPosition) {
                    while (mediaPlayer != null && mediaPlayer.isPlaying) {
                        delay(500L)
                        sliderPosition =
                            mediaPlayer.currentPosition.div(song.value.duration).toFloat()
                    }
                }
                Icon(
                    modifier = Modifier
                        .clip(CircleShape)
                        .clickable {
                            scope.launch {
                                vm.nextSong()
                            }
                        }, imageVector = Icons.Default.Info, contentDescription = ""
                )
                Icon(
                    modifier = Modifier
                        .clip(CircleShape)
                        .clickable {
                            scope.launch {
                                vm.preSong()
                                mediaPlayer.stop()
                                mediaPlayer.reset();
                                mediaPlayer.setDataSource(context, Uri.parse(song.value.uri))
                                mediaPlayer.prepareAsync();
                                if (setting.value.isPlaying.value) {
                                    mediaPlayer.start()
                                }

                            }
                        },
                    imageVector = Icons.AutoMirrored.Filled.KeyboardArrowLeft,
                    contentDescription = ""
                )
                Icon(imageVector = if (setting.value.isPlaying.value) Icons.Rounded.Close else Icons.Rounded.PlayArrow,
                    contentDescription = "",
                    modifier = Modifier
                        .clip(CircleShape)
                        .size(60.dp)
                        .clickable(mediaPlayer != null) {
                            duration = mediaPlayer.duration //milliseconds
                            setting.value.isPlaying.value = mediaPlayer.isPlaying
                            if (setting.value.isPlaying.value) {
                                mediaPlayer.pause()
                                settingVm.Playing(false)
                            } else {
                                mediaPlayer.start()
                                settingVm.Playing(true)
                            }
                        })
                Icon(
                    modifier = Modifier
                        .clip(CircleShape)
                        .clickable {
                            scope.launch {
                                mediaPlayer.stop()
                                mediaPlayer.reset();
                                vm.nextSong()
                                mediaPlayer.setDataSource(context, Uri.parse(song.value.uri))
                                mediaPlayer.prepareAsync();
                                if (setting.value.isPlaying.value) {
                                    mediaPlayer.start()
                                }
                            }
                        },
                    imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight,
                    contentDescription = ""
                )
                Icon(
                    modifier = Modifier
                        .clip(CircleShape)
                        .clickable {
                            scope.launch {
                                settingVm.showPlaylist(true)
                            }
                        }, imageVector = Icons.Default.Menu, contentDescription = ""
                )
            }
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(60.dp)
                    .background(Color.Transparent),
                horizontalArrangement = Arrangement.SpaceEvenly,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Icon(
                    modifier = Modifier.clickable {
                        scope.launch {
                            while (setting.value.isPlaying.value) {
                                delay(500L)
                                sliderPosition = sliderPosition.plus(1f.div(song.value.duration))
                            }
                        }
                    }, imageVector = Icons.Default.Refresh, contentDescription = ""
                )
                Icon(
                    modifier = Modifier.clickable {
                        scope.launch {
                            while (setting.value.isPlaying.value) {
                                delay(500L)
                                sliderPosition = sliderPosition.plus(1f.div(song.value.duration))
                            }
                        }
                    }, imageVector = Icons.Default.KeyboardArrowDown, contentDescription = ""
                )
                Icon(
                    modifier = Modifier.clickable {
                        scope.launch {
                            settingVm.showPlaylist(false)
                        }
                    }, imageVector = Icons.AutoMirrored.Filled.List, contentDescription = ""
                )
            }

        }


    }

    @Composable
    fun PlayBottomItem(
        modifier: Modifier = Modifier,
        setting: State<PlayingSetting>,
        vm: PlayingMusicVm = hiltViewModel(),
        settingVm: PlayingSettingVm = hiltViewModel(),
    ) {
        val song = vm.currentSong
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .background(Color.White)
                .then(modifier)
                .padding(PaddingSize.Normal.size),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.spacedBy(20.dp)
        ) {
            Image(painter = rememberAsyncImagePainter(
                model = ImageBuild.CoilImageRequest(
                    LocalContext.current, File(song.value.icon)
                )
            ),
                contentDescription = "",
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .size(40.dp)
                    .aspectRatio(1f)
                    .shadow(elevation = 2.dp, shape = CircleShape, clip = true)
                    .border(PaddingSize.Normal.size, Color.Black, CircleShape)
                    .clickable {
                        settingVm.showPlaylist(false)
                    })
            Text(text = song.value.title + "-" + song.value.artist,
                overflow = TextOverflow.Visible,
                modifier = Modifier
                    .weight(1f)
                    .clickable {
                        settingVm.showPlaylist(false)
                        settingVm.showPlayingPage(true)
                    })
            Box(
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    imageVector = Icons.Filled.PlayArrow,
                    contentDescription = "",
                    modifier = Modifier
                        .size(PaddingSize.Normal.size)
                        .aspectRatio(1f)
                )
                // 圆形进度条
                CircularProgressIndicator(
                    progress = { 0.2f },
                    modifier = Modifier.size(PaddingSize.Normal.size),
                    color = Color.Black,
                    trackColor = Color.LightGray,
                    strokeWidth = 2.dp
                )
            }

            Icon(imageVector = Icons.Filled.Menu,
                contentDescription = "",
                Modifier
                    .size(PaddingSize.Normal.size)
                    .aspectRatio(1f)
                    .padding(0.dp, 0.dp, 0.dp, 0.dp)
                    .clickable {
                        settingVm.showPlayingPage(false)
                        settingVm.showPlaylist(true)
                    })

        }
        OpenPlayingListPage(setting = setting, vm = vm, settingVm = settingVm)
        OpenPlayingPage(setting = setting, vm = vm)
    }
}

